package segmented_control.widget.custom.ohos.com.segmentedcontrol;


import ohos.agp.components.AttrSet;
import ohos.agp.components.LayoutScatter;
import ohos.agp.utils.Color;
import ohos.app.Context;

import org.jetbrains.annotations.NotNull;

import section_layout.widget.custom.ohos.com.sectionlayout.SectionLayout;
import section_layout.widget.custom.ohos.com.sectionlayout.utils.AttrUtils;
import section_layout.widget.custom.ohos.com.sectionlayout.utils.JUtils;

import segmented_control.widget.custom.ohos.com.segmentedcontrol.custom_segment.SegmentAdapterImpl;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.custom_segment.SegmentViewHolderImpl;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.item_row_column.SegmentAdapter;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.item_row_column.SegmentViewHolder;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.listeners.OnSegmentClickListener;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.listeners.OnSegmentSelectRequestListener;
import segmented_control.widget.custom.ohos.com.segmentedcontrol.listeners.OnSegmentSelectedListener;

import view_component.lib_ohos.com.view_component.base_view.layouts.ComponentFrameLayout;

import java.util.List;

import static segmented_control.widget.custom.ohos.com.segmentedcontrol.item_row_column.SegmentDecoration.DEFAULT_SELECTION_ANIMATION_DURATION;


/**
 * Created by Robert Apikyan on 8/18/2017.
 * /*     Attributes
 * <attr name="distributeEvenly" format="boolean" /> {@link #setDistributeEvenly(boolean)}
 * <attr name="reselectionEnabled" format="boolean" /> {@link #setReselectionEnabled(boolean)}
 * <attr name="columnCount" format="integer" /> {@link #setColumnCount(int)}
 * <attr name="segments" format="reference" /> {@link #addSegments(Object[])} {@link #addSegments(List)}
 * <attr name="supportedSegmentsCount" format="reference"/> {@link #setSupportedSelectionsCount(int)}
 * <attr name="selectedStrokeColor" format="color" /> {@link #setSelectedStrokeColor(int)}
 * <attr name="unSelectedStrokeColor" format="color" /> {@link #setUnSelectedStrokeColor(int)}
 * <attr name="strokeWidth" format="dimension" />{@link #setStrokeWidth(int)}
 * <attr name="selectedBackgroundColor" format="color" /> {@link #setSelectedBackgroundColor(int)}
 * <attr name="unSelectedBackgroundColor" format="color" /> {@link #setUnSelectedBackgroundColor(int)}
 * <attr name="selectedTextColor" format="color"/> {@link #setSelectedTextColor(int)}
 * <attr name="unSelectedTextColor" format="color"/> {@link #setUnSelectedTextColor(int)}
 * <attr name="textSize" format="dimension"/> {@link #setTextSize(int)}
 * <attr name="textHorizontalPadding" format="dimension"/> {@link #setTextHorizontalPadding(int)}
 * <attr name="textVerticalPadding" format="dimension"/> {@link #setTextVerticalPadding(int)}
 * <attr name="segmentVerticalMargin" format="dimension"/> {@link #setSegmentVerticalMargin(int)}
 * <attr name="segmentHorizontalMargin" format="dimension"/> {@link #setSegmentHorizontalMargin(int)}
 * <attr name="radius" format="dimension"/> {@link #setRadius(int)}
 * <attr name="topLeftRadius" format="dimension"/> {@link #setTopLeftRadius(int)}
 * <attr name="topRightRadius" format="dimension"/> {@link #setTopRightRadius(int)}
 * <attr name="bottomRightRadius" format="dimension"/> {@link #setBottomRightRadius(int)}
 * <attr name="bottomLeftRadius" format="dimension"/> {@link #setBottomLeftRadius(int)}
 * <attr name="radiusForEverySegment" format="boolean"/> {@link #setRadiusForEverySegment(boolean)}
 *
 * @param <D>
 */
public class SegmentedControl<D> extends ComponentFrameLayout<SegmentedControlViewComponent<D>,
        SegmentedControlControllerComponent<D>> {
    /**
     * reselectionEnabled
     */
    private boolean reselectionEnabled;
    /**
     * selectedStrokeColor
     */
    private int selectedStrokeColor;
    /**
     * unSelectedStrokeColor
     */
    private int unSelectedStrokeColor;
    /**
     * selectedBackgroundColor
     */
    private int selectedBackgroundColor;
    /**
     * unSelectedBackgroundColor
     */
    private int unSelectedBackgroundColor;
    /**
     * focusedBackgroundColor
     */
    private int focusedBackgroundColor;
    /**
     * selectedTextColor
     */
    private int selectedTextColor;
    /**
     * unSelectedTextColor
     */
    private int unSelectedTextColor;
    /**
     * strokeWidth
     */
    private int strokeWidth;
    /**
     * textSize
     */
    private int textSize;
    /**
     * textVerticalPadding
     */
    private int textVerticalPadding;
    /**
     * textHorizontalPadding
     */
    private int textHorizontalPadding;
    /**
     * segmentVerticalMargin
     */
    private int segmentVerticalMargin;
    /**
     * segmentHorizontalMargin
     */
    private int segmentHorizontalMargin;
    /**
     * radius
     */
    private int radius;
    /**
     * topLeftRadius
     */
    private int topLeftRadius;
    /**
     * topRightRadius
     */
    private int topRightRadius;
    /**
     * bottomRightRadius
     */
    private int bottomRightRadius;
    /**
     * bottomLeftRadius
     */
    private int bottomLeftRadius;
    /**
     * radiusForEverySegment
     */
    private boolean radiusForEverySegment;
    /**
     * segments
     */
    private String segments;
    /**
     * distributeEvenly
     */
    private boolean distributeEvenly;
    /**
     * columnCount
     */
    private int columnCount;
    /**
     * selectionAnimationDuration
     */
    private int selectionAnimationDuration;
    /**
     * supportedSelectionsCount
     */
    private int supportedSelectionsCount;

    public SegmentedControl(Context context) {
        super(context);
        init();
    }

    public SegmentedControl(Context context, AttrSet attrs) {
        super(context, attrs);
        init();
        initAttr(attrs);
    }

    public SegmentedControl(Context context, AttrSet attrs, String defStyle) {
        super(context, attrs, defStyle);
        init();
        initAttr(attrs);
    }

    private void init() {
        fetchAccentColor();
    }

    private void initAttr(AttrSet attrs) {
        attrDistributeEvenly(attrs);
        attrReselectionEnabled(attrs);
        attrColumnCount(attrs);
        attrSupportedSelectionsCount(attrs);
        attrSelectedStrokeColor(attrs);
        attrUnSelectedStrokeColor(attrs);
        attrStrokeWidth(attrs);
        attrSelectedBackgroundColor(attrs);
        attrFocusedBackgroundColor(attrs);
        attrUnSelectedBackgroundColor(attrs);
        attrSelectedTextColor(attrs);
        attrUnSelectedTextColor(attrs);
        attrTextSize(attrs);
        attrSegmentVerticalMargin(attrs);
        attrTextVerticalPadding(attrs);
        attrTextHorizontalPadding(attrs);
        attrSegmentHorizontalMargin(attrs);
        attrTopLeftRadius(attrs);
        attrTopRightRadius(attrs);
        attrBottomRightRadius(attrs);
        attrBottomLeftRadius(attrs);
        attrRadius(attrs);
        attrRadiusForEverySegment(attrs);
        attrSelectionAnimationDuration(attrs);
        attrSegments(attrs);
    }

    private void fetchAccentColor() {
        int accentColor = Color.getIntColor("#00DAC5");
        getControllerComponent().setAccentColor(accentColor);
        this.selectedStrokeColor = accentColor;
        this.unSelectedStrokeColor = accentColor;
        this.selectedBackgroundColor = accentColor;
        this.unSelectedTextColor = accentColor;
        this.strokeWidth = 1;
        this.unSelectedBackgroundColor = Color.TRANSPARENT.getValue();
    }

    private void attrSelectedStrokeColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "selectedStrokeColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                selectedStrokeColor = color;
                getControllerComponent().setSelectedStrokeColor(selectedStrokeColor);
            }
        });
    }

    private void attrUnSelectedStrokeColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "unSelectedStrokeColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                unSelectedStrokeColor = color;
                getControllerComponent().setUnSelectedStrokeColor(unSelectedStrokeColor);
            }
        });
    }

    private void attrStrokeWidth(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "strokeWidth", new Consumer<Integer>() {
            @Override
            public void apply(Integer width) {
                strokeWidth = width;
                getControllerComponent().setStrokeWidth(strokeWidth);
            }
        });
    }

    private void attrSelectionAnimationDuration(AttrSet attrSet) {
        selectionAnimationDuration = AttrUtils.getDimensionFromAttr(attrSet, "selectionAnimationDuration", DEFAULT_SELECTION_ANIMATION_DURATION);
        getControllerComponent().setSelectionAnimationDuration(selectionAnimationDuration);
    }

    private void attrSelectedBackgroundColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "selectedBackgroundColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                selectedBackgroundColor = color;
                getControllerComponent().setSelectedBackgroundColor(selectedBackgroundColor);
            }
        });
    }

    private void attrUnSelectedBackgroundColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "unSelectedBackgroundColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                unSelectedBackgroundColor = color;
                getControllerComponent().setUnSelectedBackgroundColor(unSelectedBackgroundColor);
            }
        });
    }

    private void attrFocusedBackgroundColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "focusedBackgroundColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                focusedBackgroundColor = color;
                getControllerComponent().setFocusedBackgroundColor(focusedBackgroundColor);
            }
        });
    }

    private void attrSelectedTextColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "selectedTextColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                selectedTextColor = color;
                getControllerComponent().setSelectedTextColor(selectedTextColor);
            }
        });
    }

    private void attrUnSelectedTextColor(AttrSet attrSet) {
        obtainColorAttr(attrSet, "unSelectedTextColor", new Consumer<Integer>() {
            @Override
            public void apply(Integer color) {
                unSelectedTextColor = color;
                getControllerComponent().setUnSelectedTextColor(unSelectedTextColor);
            }
        });
    }

    private void attrTextSize(AttrSet attrSet) {
        textSize = AttrUtils.getDimensionFromAttr(attrSet, "textSize", (int) JUtils.vp2px(getContext(), 14));
        if (textSize > 0) {
            getControllerComponent().setTextSize(textSize);
        }
    }

    private void attrTextVerticalPadding(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "textVerticalPadding", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                textVerticalPadding = dimen;
                getControllerComponent().setTextVerticalPadding(textVerticalPadding);
            }
        });
    }

    private void attrTextHorizontalPadding(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "textHorizontalPadding", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                textHorizontalPadding = dimen;
                getControllerComponent().setTextHorizontalPadding(textHorizontalPadding);
            }
        });
    }

    private void attrSegmentVerticalMargin(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "segmentVerticalMargin", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                segmentVerticalMargin = dimen;
                getControllerComponent().setSegmentVerticalMargin(segmentVerticalMargin);
            }
        });
    }

    private void attrSegmentHorizontalMargin(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "segmentHorizontalMargin", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                segmentHorizontalMargin = dimen;
                getControllerComponent().setSegmentHorizontalMargin(segmentHorizontalMargin);
            }
        });
    }

    private void attrRadius(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "radius", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                radius = dimen;
                getControllerComponent().setRadius(radius);
            }
        });
    }

    private void attrTopLeftRadius(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "topLeftRadius", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                topLeftRadius = dimen;
                getControllerComponent().setTopLeftRadius(topLeftRadius);
            }
        });
    }

    private void attrTopRightRadius(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "topRightRadius", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                topRightRadius = dimen;
                getControllerComponent().setTopRightRadius(topRightRadius);
            }
        });
    }

    private void attrBottomRightRadius(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "bottomRightRadius", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                bottomRightRadius = dimen;
                getControllerComponent().setBottomRightRadius(bottomRightRadius);
            }
        });
    }

    private void attrBottomLeftRadius(AttrSet attrSet) {
        obtainDimensionAttr(attrSet, "bottomLeftRadius", new Consumer<Integer>() {
            @Override
            public void apply(Integer dimen) {
                bottomLeftRadius = dimen;
                getControllerComponent().setBottomLeftRadius(bottomLeftRadius);
            }
        });
    }

    private void attrRadiusForEverySegment(AttrSet attrSet) {
        radiusForEverySegment = AttrUtils.getBooleanFromAttr(attrSet, "radiusForEverySegment", false);
        getControllerComponent().setRadiusForEverySegment(radiusForEverySegment);
    }

    private void attrSegments(AttrSet attrSet) {
        String[] list;
        segments = AttrUtils.getStringFromAttr(attrSet, "segments", "");
        if (segments.contains(",")) {
            list = segments.split(",");
        } else {
            list = new String[]{segments};
        }
        useDefaultAdapter();
        //noinspection unchecked
        getControllerComponent().addSegments((D[]) list);
    }

    private void attrColumnCount(AttrSet attrSet) {
        columnCount = AttrUtils.getIntegerFromAttr(attrSet, "columnCount", Configs.DEFAULT_COLUMN_COUNT);
        getControllerComponent().setColumnCount(columnCount);
        notifyConfigIsChanged();
    }

    private void attrSupportedSelectionsCount(AttrSet attrSet) {
        supportedSelectionsCount = AttrUtils.getIntegerFromAttr(attrSet, "supportedSelectionsCount", Configs.DEFAULT_SUPPORTED_SELECTIONS_COUNT);
        if (supportedSelectionsCount > 0) {
            getControllerComponent().setSupportedSelectionsCount(supportedSelectionsCount);
        }
    }

    private void attrDistributeEvenly(AttrSet attrSet) {
        distributeEvenly = AttrUtils.getBooleanFromAttr(attrSet, "distributeEvenly", false);
        getControllerComponent().setDistributeEvenly(distributeEvenly);
        getControllerComponent().notifyConfigIsChanged();
    }

    private void attrReselectionEnabled(AttrSet attrSet) {
        reselectionEnabled = AttrUtils.getBooleanFromAttr(attrSet, "reselectionEnabled", true);
        getControllerComponent().setReselectionEnabled(reselectionEnabled);
    }

    private void obtainColorAttr(AttrSet attrSet, String attr, Consumer<Integer> colorConsumer) {
        int color = AttrUtils.getColorFromAttr(attrSet, attr, -2); // -1 is white
        if (color != -2) {
            colorConsumer.apply(color);
        }
    }

    private void obtainDimensionAttr(AttrSet attrSet, String attr, Consumer<Integer> dimensionConsumer) {
        int dimensionPixelSize = AttrUtils.getDimensionFromAttr(attrSet, attr, -1);
        if (dimensionPixelSize != -1) {
            dimensionConsumer.apply(dimensionPixelSize);
        }
    }

    @NotNull
    @Override
    public SegmentedControlViewComponent<D> createViewComponent(@NotNull LayoutScatter layoutInflater) {
        addComponent(new SectionLayout<D>(getContext()), 0);
        return new SegmentedControlViewComponent<>(this);
    }

    @NotNull
    @Override
    public SegmentedControlControllerComponent<D> createControllerComponent() {
        return new SegmentedControlControllerComponent<>();
    }

    /**
     * Will enabled multy selection, default value is 1, only one item can be selected at the time
     *
     * @param supportedSelectionsCount specifies the count of selected segments at the same time,
     *                                 if the selection count is reached the elder selection
     *                                 will be unselected
     */
    public void setSupportedSelectionsCount(int supportedSelectionsCount) {
        Assert.supportedSelectionsCount(supportedSelectionsCount);
        getControllerComponent().setSupportedSelectionsCount(supportedSelectionsCount);
    }

    /**
     * setColumnCount
     *
     * @param columnCount The column count for SegmentedControl
     */
    public void setColumnCount(int columnCount) {
        Assert.columnCount(columnCount);
        getControllerComponent().setColumnCount(columnCount);
    }

    /**
     * setAdapter
     *
     * @param adapter NonNull adapter (extended from {@link SegmentAdapter})
     */
    private void setAdapter(@NotNull SegmentAdapter adapter) {
        Assert.adapter(adapter);
        getControllerComponent().setAdapter(adapter);
    }

    /**
     * set the adapter {@link SegmentAdapter} with {@link SegmentViewHolderImpl} view holder
     * where data D data type is String. use segmentedControl.addSegments(String[] segmentDataArray) or segmentedControl.addSegments(List<String> segmentDataList) methods
     */
    private void useDefaultAdapter() {
        setAdapter(new SegmentAdapterImpl());
    }

    /**
     * Add segments to segmentController
     *
     * @param segmentData specified array Data type
     */
    public void addSegments(D[] segmentData) {
        getControllerComponent().addSegments(segmentData);
    }

    /**
     * Add segments to segmentController
     *
     * @param segmentData specified list Data type
     */
    public void addSegments(List<D> segmentData) {
        getControllerComponent().addSegments(segmentData);
    }

    /**
     * setDistributeEvenly
     *
     * @param willDistributeEvenly true each section width with will be equal to each other,
     *                              false each section width will be measured depending on its content width;
     */
    public void setDistributeEvenly(boolean willDistributeEvenly) {
        getControllerComponent().setDistributeEvenly(willDistributeEvenly);
    }

    /**
     * setReselectionEnabled
     *
     * @param isEnabled if true second click to segment will not turn it from selected to unselected state,
     *                  if false the second click will turn it from selected to un selected state,
     *                  default value is true
     */
    public void setReselectionEnabled(boolean isEnabled) {
        getControllerComponent().setReselectionEnabled(isEnabled);
    }

    /**
     * addOnSegmentClickListener
     *
     * @param onSegmentClickListener every time click event will be notified,
     *                                even if the segment is already selected
     */
    public void addOnSegmentClickListener(OnSegmentClickListener<D> onSegmentClickListener) {
        getControllerComponent().addOnSegmentClickListener(onSegmentClickListener);
    }

    /**
     * removeOnSegmentClickListener
     *
     * @param onSegmentClickListener every time click event will be notified,
     *                                even if the segment is already selected
     *                                <p>
     *                                Remove listener
     */
    public void removeOnSegmentClickListener(OnSegmentClickListener<D> onSegmentClickListener) {
        getControllerComponent().removeOnSegmentClickListener(onSegmentClickListener);
    }

    /**
     * addOnSegmentSelectListener
     *
     * @param onSegmentSelectedListener event will be notified, when segment is selected and unSelected and reselected,
     *                                   for more info check out {@link OnSegmentSelectedListener} class
     */
    public void addOnSegmentSelectListener(OnSegmentSelectedListener<D> onSegmentSelectedListener) {
        getControllerComponent().addOnSegmentSelectListener(onSegmentSelectedListener);
    }

    /**
     * removeOnSegmentSelectListener
     *
     * @param onSegmentSelectedListener event will be notified, when segment is selected and unSelected and reselected,
     *                                   for more info check out {@link OnSegmentSelectedListener} class
     *                                   <p>
     *                                   Remove listener
     */
    public void removeOnSegmentSelectListener(OnSegmentSelectedListener<D> onSegmentSelectedListener) {
        getControllerComponent().removeOnSegmentSelectListener(onSegmentSelectedListener);
    }

    /**
     * setOnSegmentSelectRequestListener
     *
     * @param onSegmentSelectRequestListener event will be triggered after click event and before selection event
     *                                        for more info click out {@link OnSegmentSelectRequestListener} class
     */
    public void setOnSegmentSelectRequestListener(OnSegmentSelectRequestListener<D> onSegmentSelectRequestListener) {
        getControllerComponent().setOnSegmentSelectRequestListener(onSegmentSelectRequestListener);
    }

    /**
     * Removes all segments
     */
    public void removeAllSegments() {
        getControllerComponent().removeAllSegments();
    }

    /**
     * find the segment view holder with the segment absolute position
     *
     * @param position the segment position
     * @return SegmentViewHolder instance for specified position
     */
    private SegmentViewHolder<D> findSegmentByAbsolutePosition(int position) {
        Assert.outOfBounds(position, size(), "SegmentedControl#findSegmentByAbsolutePosition");
        return getControllerComponent().findSegmentByAbsolutePosition(position);
    }

    /**
     * find the segment with column number and row position
     *
     * @param column Segment column number
     * @param row Segment row position
     * @return SegmentViewHolder instance for specified column and row numbers
     */
    private SegmentViewHolder<D> findSegmentByColumnAndRow(int column, int row) {
        Assert.outOfBounds(getControllerComponent().getAbsolutePosition(column, row), size(), "SegmentedControl#setSelectedSegment");
        return getControllerComponent().findSegmentByColumnAndRow(column, row);
    }

    /**
     * Select the selected position
     *
     * @param position Segment position
     */
    public void setSelectedSegment(int position) {
        Assert.outOfBounds(position, size(), "SegmentedControl#setSelectedSegment");
        getControllerComponent().setSelectedSegment(position);
    }

    /**
     * Select the segment with specified column number and row position
     *
     * @param column Segment column number
     * @param row Segment row position
     */
    public void setSelectedSegment(int column, int row) {
        Assert.outOfBounds(getControllerComponent().getAbsolutePosition(column, row), size(), "SegmentedControl#setSelectedSegment");
        getControllerComponent().setSelectedSegment(column, row);
    }

    /**
     * Iterate on segments, and pass the view holders as an argument for {@link SegmentConsumer}
     *
     * @param segmentConsumer Segment consumer
     */
    private void forEachSegment(SegmentConsumer<D> segmentConsumer) {
        getControllerComponent().forEachSegment(segmentConsumer);
    }

    public void setSelectedStrokeColor(int color) {
        getControllerComponent().setSelectedStrokeColor(color);
    }

    public void setUnSelectedStrokeColor(int color) {
        getControllerComponent().setUnSelectedStrokeColor(color);
    }

    public void setFocusedBackgroundColor(int color) {
        getControllerComponent().setFocusedBackgroundColor(color);
    }

    /**
     * Set segments selection animation duration value
     *
     * @param duration in milliseconds
     */
    public void setSelectionAnimationDuration(int duration) {
        getControllerComponent().setSelectionAnimationDuration(duration);
    }

    public void setStrokeWidth(int width) {
        getControllerComponent().setStrokeWidth(width);
    }

    public void setSelectedBackgroundColor(int color) {
        getControllerComponent().setSelectedBackgroundColor(color);
    }

    public void setUnSelectedBackgroundColor(int color) {
        getControllerComponent().setUnSelectedBackgroundColor(color);
    }

    public void setSelectedTextColor(int color) {
        getControllerComponent().setSelectedTextColor(color);
    }

    public void setUnSelectedTextColor(int color) {
        getControllerComponent().setUnSelectedTextColor(color);
    }

    public void setTextSize(int textSize) {
        getControllerComponent().setTextSize(textSize);
    }


    public void setTextVerticalPadding(int padding) {
        getControllerComponent().setTextVerticalPadding(padding);
    }

    public void setTextHorizontalPadding(int padding) {
        getControllerComponent().setTextHorizontalPadding(padding);
    }

    public void setSegmentVerticalMargin(int margin) {
        getControllerComponent().setSegmentVerticalMargin(margin);
    }

    public void setSegmentHorizontalMargin(int margin) {
        getControllerComponent().setSegmentHorizontalMargin(margin);
    }

    public void setRadius(int radius) {
        getControllerComponent().setRadius(radius);
    }

    public void setTopLeftRadius(int radius) {
        getControllerComponent().setTopLeftRadius(radius);
    }

    public void setTopRightRadius(int radius) {
        getControllerComponent().setTopRightRadius(radius);
    }

    public void setBottomRightRadius(int radius) {
        getControllerComponent().setBottomRightRadius(radius);
    }

    public void setBottomLeftRadius(int radius) {
        getControllerComponent().setBottomLeftRadius(radius);
    }

    /**
     * setRadiusForEverySegment
     *
     * @param radiusForEverySegment true every segment corners will be rounded, false only top left,top right, bottom right and bottom left corners will be rounded
     */
    public void setRadiusForEverySegment(boolean radiusForEverySegment) {
        getControllerComponent().setRadiusForEverySegment(radiusForEverySegment);
    }

    /**
     * clearSelection
     *
     * Removes the last selected segment selection, SegmentViewHolder's onSegmentSelected  method will be called
     * with isSelected = false, isReselected = false
     */
    public void clearSelection() {
        getControllerComponent().clearSelection(false);
    }

    /**
     * Removes the last selected segment selection, SegmentViewHolder's onSegmentSelected  method will be called
     * with isSelected = false, isReselected = false.
     *
     * @param notifySegmentSelectedListener if true SegmentSelectedListeners will be notified.
     */
    public void clearSelection(boolean notifySegmentSelectedListener) {
        getControllerComponent().clearSelection(notifySegmentSelectedListener);
    }

    /**
     * Call this method after every configuration change
     * setColumnCount, setRadius et...
     */
    private void notifyConfigIsChanged() {
        getControllerComponent().notifyConfigIsChanged();
    }

    private int size() {
        return getControllerComponent().size();
    }

//    public SegmentViewHolder<D> getSelectedViewHolder() {
//        return getControllerComponent().getSelectedViewHolder();
//    }
    public int[] getLastSelectedColumnAndRow() {
        return getControllerComponent().getLastSelectedColumnAndRow();
    }

    public int getLastSelectedAbsolutePosition() {
        return getControllerComponent().getLastSelectedAbsolutePosition();
    }

    public boolean hasSelectedSegment() {
        return getControllerComponent().isSelected();
    }
}
